package com.internetCafes.spms.core.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.zip.ZipException;

import javax.servlet.http.HttpServletResponse;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

/**
 * ZIP文件压缩和解压(要使用apache ant.jar以处理中文乱码)
 * 
 * @author sunjun
 * @version 2.0
 */
public class ZipUtil {

	private static final int BUFFER = 104;


	/**
	 * 压缩文件file成zip文件zipFile
	 * 
	 * @param file
	 *            要压缩的文件
	 * @param zipFile
	 *            压缩文件存放地方
	 * @throws Exception
	 */
	public static void zip(File file, File zipFile) throws Exception {
		ZipOutputStream output = null;
		try {
			output = new ZipOutputStream(new FileOutputStream(zipFile));
			// 顶层目录开始
			zipFile(output, file, "");
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			// 关闭流
			if (output != null) {
				output.flush();
				output.close();
			}
		}
	}

	/**
	 * 压缩文件为zip格式
	 * 
	 * @param ZipOutputStream对象
	 * @param file要压缩的文件或文件夹
	 * @param basePath条目根目录
	 * @throws IOException
	 */
	private static void zipFile(ZipOutputStream output, File file, String basePath) throws IOException {
		FileInputStream input = null;
		try {
			// 文件为目录
			if (file.isDirectory()) {
				// 得到当前目录里面的文件列表
				File list[] = file.listFiles();
				basePath = basePath + (basePath.length() == 0 ? "" : "/") + file.getName();
				// 循环递归压缩每个文件
				for (File f : list) {
					zipFile(output, f, basePath);
				}
			} else {
				// 压缩文件
				basePath = (basePath.length() == 0 ? "" : basePath + "/") + file.getName();
				output.putNextEntry(new ZipEntry(basePath));
				input = new FileInputStream(file);
				int readLen = 0;
				byte[] buffer = new byte[1024 * 8];
				while ((readLen = input.read(buffer, 0, 1024 * 8)) != -1) {
					output.write(buffer, 0, readLen);
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			// 关闭流
			if (input != null) {
				input.close();
			}
		}
	}

	/**
	 * 解压文件不需要目录
	 * 
	 * @param output
	 *            ZipOutputStream对象
	 * @param path
	 *            要解压的文件或文件夹的路径
	 * @param savepath
	 *            解压的目标路径
	 * @throws IOException
	 */
	public static void unZipNoFile(String fileName, String destFilePath) {
		try {
			ZipFile zipFile = new ZipFile(fileName, "GBK");
			Enumeration emu = zipFile.getEntries();
			while (emu.hasMoreElements()) {
				ZipEntry entry = (ZipEntry) emu.nextElement();
				if (entry.isDirectory()) {
					File dir = new File(destFilePath + entry.getName());
					if (!dir.exists()) {
						dir.mkdirs();
					}
					continue;
				}
				BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
				String name = getFileNameByPath(entry.getName());
				File file = new File(destFilePath + name);
				File parent = file.getParentFile();
				if (parent != null && (!parent.exists())) {
					parent.mkdirs();
				}
				FileOutputStream fos = new FileOutputStream(file);
				BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
				byte[] buf = new byte[BUFFER];
				int len = 0;
				while ((len = bis.read(buf, 0, BUFFER)) != -1) {
					fos.write(buf, 0, len);
				}
				bos.flush();
				bos.close();
				bis.close();
				System.out.println("解压文件：" + file.getName());
			}
			zipFile.close();
		} catch (ZipException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 解压文件不需要目录
	 * 
	 * @param output
	 *            ZipOutputStream对象
	 * @param path
	 *            要解压的文件或文件夹的路径
	 * @param savepath
	 *            解压的目标路径
	 * @throws IOException
	 */
	public static void unZipNoFile(File filePath, String destFilePath) {
		try {
			ZipFile zipFile = new ZipFile(filePath, "GBK");
			Enumeration emu = zipFile.getEntries();
			while (emu.hasMoreElements()) {
				ZipEntry entry = (ZipEntry) emu.nextElement();
				if (entry.isDirectory()) {
					File dir = new File(destFilePath + entry.getName());
					if (!dir.exists()) {
						dir.mkdirs();
					}
					continue;
				}
				BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
				String name = getFileNameByPath(entry.getName());
				File file = new File(destFilePath + name);
				File parent = file.getParentFile();
				if (parent != null && (!parent.exists())) {
					parent.mkdirs();
				}
				FileOutputStream fos = new FileOutputStream(file);
				BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
				byte[] buf = new byte[BUFFER];
				int len = 0;
				while ((len = bis.read(buf, 0, BUFFER)) != -1) {
					fos.write(buf, 0, len);
				}
				bos.flush();
				bos.close();
				bis.close();
				System.out.println("解压文件：" + file.getName());
			}
			zipFile.close();
		} catch (ZipException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 验证文件是否存在于压缩包
	 * 
	 * @param filePath
	 * @param fileName
	 * @return
	 */
	public static boolean isExist(File filePath, String fileName) {

		boolean isExist = false;
		ZipEntry entry = null;
		String fileName_ = null;
		int index = -1;
		try {
			ZipFile zipFile = new ZipFile(filePath);
			Enumeration<?> entries = zipFile.getEntries();
			while (entries.hasMoreElements()) {
				entry = (ZipEntry) entries.nextElement();
				fileName_ = entry.getName();
				index = fileName_.lastIndexOf("/");
				if (index > -1) {
					fileName_ = fileName_.substring(index + 1);
				}
				fileName_ = fileName_.toLowerCase();
				if (fileName_.equals(fileName)) {
					isExist = true;
					break;
				} else {
					continue;
				}
			}
			zipFile.close();

		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return isExist;
	}

	/**
	 * 
	 * 判断是否为图片
	 * 
	 * @param filename
	 * @return
	 */
	public static boolean isPics(String filename) {
		boolean flag = false;
		if (filename.indexOf(".") > -1) {
			String tmpName = filename.substring(filename.lastIndexOf("."), filename.length());
			tmpName = tmpName.toLowerCase();
			if (tmpName.equals(".jpg") || tmpName.equals(".ico") || tmpName.equals(".bmp") || tmpName.equals(".png")) {
				flag = true;
			}
		}
		return flag;
	}

	public static void download(String urlString, String filename) {
		try {
			// 构造URL
			URL url = new URL(urlString);
			// 打开连接
			URLConnection con = url.openConnection();
			// 输入流
			InputStream is = con.getInputStream();
			// 1K的数据缓冲
			byte[] bs = new byte[2048];
			// 读取到的数据长度
			int len;
			// 输出的文件流
			OutputStream os = new FileOutputStream(filename);
			// 开始读取
			while ((len = is.read(bs)) != -1) {
				os.write(bs, 0, len);
			}
			// 完毕，关闭所有链接
			os.close();
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static boolean copy(String start, String end) {
		try {
			// 要拷贝的图片
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(start)));
			// 目标的地址
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(end)));
			try {
				int val = -1;
				while ((val = bis.read()) != -1) {
					bos.write(val);
				}
				bos.flush();
				bos.close();
				bis.close();
				return true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 下载zip压缩包
	 * @param filePath
	 * @param response
	 */
	 public static void downLoadZip(String filePath, HttpServletResponse response){
		 ZipOutputStream output = null;
			try {
				output = new ZipOutputStream(response.getOutputStream());
				zipFile(output, new File(filePath), "");
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				try {
					if(output != null){
						output.flush();
						output.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
	 }


	public static String getFileNameByPath(String path){
		String name = "";
		if(path != null && path.length()>0){
			int index =path.lastIndexOf("/");
			int index2 =path.lastIndexOf("\\");
			if(index > index2){
				name = path.substring(index+1);
			}else{
				name = path.substring(index2+1);
			}
		}
		return name;
	}
	
	public static void main(String[] args) {
		//System.out.println(isExist(new File("C:\\Users\\Administrator\\Desktop\\icbcDemo.zip"), "rt1.jar"));

		try {
			zip(new File("C:\\Users\\Sunny\\Desktop\\image"), new File("C:\\Users\\Sunny\\Desktop\\image.zip"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}